
# coding:utf-8

from lib import flux
from utils.suger import *
from lib.fluxext import singleton, ViewGroup
from system.skill import SKILL_LST
from utils import vec_dist

class HealBar(ViewGroup):
    def __init__(self):
        self.bg = flux.View()
        self.bg.SetSize(192, 15)
        self.bg.SetColor(0,0,0)
        self.bg.SetPos(config.SCREEN_WIDTH/2, config.SCREEN_HEIGHT-75)

        self.bar = flux.View()
        self.bar.SetSize(192, 15)
        self.bar.SetColor(1,0,0)
        self.bar.SetAnchor(self.bg)

        self.text = flux.TextView('wqySmall')
        self.text.SetColor(1,1,1)
        self.text.SetText('7/7')
        self.text.SetAnchor(self.bar)

        self.retext = flux.TextView('wqySmall')
        self.retext.SetColor(1,1,1)
        self.retext.SetAnchor(self.bg)
        self.retext.SetVisible(False)

    def SetValue(self, now, max, hpreg):
        r = 1.0*now/max
        self.text.SetVisible(True)
        self.text.SetText('%.1f/%.1f' % (now,max))
        if self.text.GetTextWidth() > 192*r:
            self.text.SetText('%.1f' % now)
            if self.text.GetTextWidth() > 192*r:
                self.text.SetVisible(False)
        self.bar.SetSize(192*r, 15)
        self.bar.SetPos(-192*(1-r)/2, 0)
        _retxt = '%+.1f' % hpreg
        self.retext.SetText('%s %s' % (_retxt[0], _retxt[1:]))
        if self.retext.GetTextWidth() <= 192*(1-r):
            self.retext.SetPos(192*r/2, 0)
            self.retext.SetVisible(True)
        else:
            self.retext.SetVisible(False)

    def AddToScreen(self, scr, layer=0):
        scr.AddView(self.bg, layer)
        scr.AddView(self.bar, layer)
        scr.AddView(self.text, layer)
        scr.AddView(self.retext, layer)

class ManaBar(ViewGroup):
    def __init__(self):
        self.bg = flux.View()
        self.bg.SetSize(192, 15)
        self.bg.SetColor(0,0,0)
        self.bg.SetPos(config.SCREEN_WIDTH/2, config.SCREEN_HEIGHT-57)

        self.bar = flux.View()
        self.bar.SetSize(192, 15)
        self.bar.SetColor(0,0,1)
        #self.bar.SetAlign(flux.ALIGN_LEFT)
        #self.bar.SetPos(-192/2, 0)
        self.bar.SetAnchor(self.bg)

        self.text = flux.TextView('wqySmall')
        self.text.SetColor(1,1,1)
        self.text.SetText('7/7')
        self.text.SetAnchor(self.bar)
        
        self.retext = flux.TextView('wqySmall')
        self.retext.SetColor(1,1,1)
        self.retext.SetAnchor(self.bg)
        self.retext.SetVisible(False)
        
    def SetValue(self, now, max, mpreg):
        r = 1.0*now/max
        self.text.SetVisible(True)
        self.text.SetText('%.1f/%.1f' % (now,max))
        if self.text.GetTextWidth() > 192*r:
            self.text.SetText('%.1f' % now)
            if self.text.GetTextWidth() > 192*r:
                self.text.SetVisible(False)
        self.bar.SetSize(192*r, 15)
        self.bar.SetPos(-192*(1-r)/2, 0)
        _retxt = '%+.1f' % mpreg
        self.retext.SetText('%s %s' % (_retxt[0], _retxt[1:]))
        if self.retext.GetTextWidth() <= 192*(1-r):
            self.retext.SetPos(192*r/2, 0)
            self.retext.SetVisible(True)
        else:
            self.retext.SetVisible(False)

    def AddToScreen(self, scr, layer=0):
        scr.AddView(self.bg, layer)
        scr.AddView(self.bar, layer)
        scr.AddView(self.text, layer)
        scr.AddView(self.retext, layer)

class SkillTip(ViewGroup):
    def __init__(self):
        self.bg = flux.View()
        self.bg.SetColor(0,0,0)
        self.bg.SetAlign(flux.ALIGN_BOTTOMLEFT)

        self.text = flux.RichTextView('wqySmall')
        self.text.SetColor(1,1,1)
        self.text.SetAlign(flux.ALIGN_BOTTOMLEFT)
        self.text.SetAnchor(self.bg)
        self.text.SetPos(5,-5)

    def SetPos(self, x, y):
        self.bg.SetPos(x, y)

    def SetText(self, txt):
        self.text.SetText(txt)
        size = self.text.GetSize()
        self.bg.SetSize(size.x + 10, size.y + 10)

    def AddToScreen(self, scr, layer=0):
        scr.AddView(self.bg, layer+1)
        scr.AddView(self.text, layer+1)


class SkillButton(ViewGroup):
    def __init__(self):
        self.bg = flux.View()
        self.bg.SetColor(0,0,0)

        self.sklimg = flux.ImgView()
        
        self.cd = flux.View()
        self.cd.SetColor(0,0,0, 0.5)
        self.cd.SetAlign(flux.ALIGN_BOTTOM)

        self.keytip = flux.TextView('wqySmall')
        self.keytip.SetColor(1,1,1)
        self.keytip.SetText('?')
        self.keytip.SetAlign(flux.ALIGN_BOTTOMRIGHT)

        self.key = None
        self.keytip.SetAnchor(self.bg)
        self.sklimg.SetAnchor(self.bg)
        self.cd.SetAnchor(self.bg)
        self.skl = None

    def PtInView(self, x, y):
        return self.bg.PtInView(x, y)

    def SetPos(self, x, y):
        self.bg.SetPos(x, y)
        #self.sklimg.SetPos(x, y)

    def SetSprite(self, fn, frame=1, line=1):
        self.sklimg.SetSprite(fn, frame, line)

    def SetColor(self, r, g, b, a=1):
        self.sklimg.SetColor(r, g, b, a)

    def SetKeyTip(self, key):
        self.key = key
        self.keytip.SetText(key)

    def SetSize(self, width, height):
        self.width, self.height = width, height
        self.bg.SetSize(width, height)
        self.sklimg.SetSize(width, height)
        self.cd.SetSize(width, 0)
        self.cd.SetPos(0, height/2)
        self.keytip.SetPos(width/2-2, height/2-1)
        
    def SetSkill(self, skl_id):
        self.skl = SKILL_LST[skl_id]
        if self.skl:
            self.SetSprite(self.skl.sprite)

    def Cast(self):
        on_control = Game().on_control
        if self.skl and on_control:
            sid = self.skl.id
            ret = on_control.skill.check(sid)
            if ret:
                if ret == 1:
                    Game().log.add('这个技能还在冷却中')
                elif ret == 2:
                    Game().log.add('不能满足施法要求')
                elif ret == 3:
                    Game().log.add('没有足够的魔法')
            else:
                on_control.skill.cast(sid)
                Game().log.add('%s 法术熟练度 + 1' % self.skl.name)

                self.cd.SetSize(self.width, self.height)
                self.cd.Anim().AnimClear()
                self.cd.Anim().SizeTo(self.skl.cd, flux.utils.Vec2i(self.width, 0))
                self.cd.Anim().Do()

    def update_state(self):
        '''状态更新，比如把不能释放的技能标成红色'''
        pass

    def AddToScreen(self, scr, layer=0):
        scr.AddView(self.bg, layer)
        scr.AddView(self.sklimg, layer)
        scr.AddView(self.cd, layer)
        scr.AddView(self.keytip, layer)


@singleton
class BattleInfo():
    def __init__(self):
        self.txt = flux.TextView('wqySmall')
        self.txt.SetAlpha(0)
        self.txt.Anim().AlphaTo(1.5, 1, 0)
        self.txt.SetPos(0, -30)

    def AddTxt(self, txt, color=[1,0,1]):
        self.txt.SetColor(*color)
        self.txt.SetText(txt)
        self.txt.Anim().AnimReset()
        self.txt.Anim().Do()

    def SetAnchor(self, anchor):
        self.txt.SetAnchor(anchor)


@singleton
class Lock(ViewGroup):
    lock_lst = []

    def __init__(self):
        self.v = flux.ShapeView()
        self.v.SetColor(0,0,1)
        self.v.AddRect(50,50, 2,2, False, 1)
        self.v.AddLine(-20, 0, 20, 0)
        self.v.AddLine(0, 20, 0, -20)
        self.v.Done()
        self.SetVisible(False)

        @smokesignal.on('unit_dead')
        def _callback(unit):
            if unit == Game().on_control.aim:
                Game().on_control.aim = None
                self.SetVisible(False)

    def at(self, unit):
        self.v.SetAnchor(unit.GetAnchor())

    def focus(self):
        if not self.lock_lst:
            if Game().on_control.aim:
                self.SetVisible(False)
                Game().on_control.aim = None
                return
            else:
                self.calc()

        if self.lock_lst:
            self.SetVisible(True)
            last = self.lock_lst.pop()
            Game().on_control.aim = last
            self.v.SetAnchor(last.GetAnchor())

    def calc(self):
        player = Game().on_control
        range = 400
        tab = {}

        if player:
            for i in Game().ai.enemy:
                dist = vec_dist(player.GetPos(), i.GetPos())
                if dist < range:
                    while dist in tab:
                        dist += 0.00001
                    tab[dist] = i
            for k,v in tab.items():
                self.lock_lst.append(v)
